﻿using Payroll.BusinessLogic.Caching;
using Payroll.BusinessLogic.Data;
using Payroll.Common;
using Payroll.Common.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Payroll.BusinessLogic.Devices
{
    public partial class OrderService : IOrderService
    {
        #region Fields

        /// <summary>
        /// Object context
        /// </summary>
        private readonly PayrollHRDataContext m_context;

        /// <summary>
        /// Cache manager
        /// </summary>
        private readonly ICacheManager _cacheManager;
       
        #endregion
        #region Ctor

        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="context">Object context</param>
        public OrderService(PayrollHRDataContext context)
        {
            this.m_context = context;
            this._cacheManager = new PayrollRequestCache();
        }

        #endregion
        #region Function
        protected int SaveOrder(Order order)
        {
            var item = (from o in m_context.Orders
                        where o.OrderID == order.OrderID
                        select o).FirstOrDefault();
            if (!CommonHelper.IsNull(item))
            {
                item.Transdate = order.Transdate;
                item.Note = order.Note;
                item.Modified = order.Modified;
                item.ModifiedDate = order.ModifiedDate;
            }
            else {
                item = new Data.Order
                {
                    Transdate = order.Transdate,
                    Note = order.Note,
                    Createby = order.Createby,
                    Modified = order.Modified,
                    CreateDate = order.CreateDate,
                    ModifiedDate = order.ModifiedDate
                };
                m_context.Orders.InsertOnSubmit(item);
            }
            m_context.SubmitChanges();

            return item.OrderID;
        }
        /// <summary>
        /// Saves the order device.
        /// </summary>
        /// <param name="List">The list.</param>
        /// <param name="OrderID">The order ID.</param>
        protected void SaveOrderDevice(List<OrderDevice> List, int OrderID)
        {
            m_context.OrderDevices.DeleteAllOnSubmit(from od in m_context.OrderDevices where od.OrderID == OrderID select od);
            m_context.SubmitChanges();
            m_context.OrderDevices.InsertAllOnSubmit(this.TranferOrderDevice(List, OrderID));
            m_context.SubmitChanges();
        }
        /// <summary>
        /// Tranfers the order device.
        /// </summary>
        /// <param name="List">The list.</param>
        /// <param name="OrderID">The order ID.</param>
        /// <returns></returns>
        private List<Data.OrderDevice> TranferOrderDevice(List<OrderDevice> List, int OrderID)
        {
            List<Data.OrderDevice> Lst = new List<Data.OrderDevice>();
            foreach (var info in List)
            {
                Lst.Add(new Data.OrderDevice { DeviceID = info.DeviceID, OrderID = OrderID, Quantity = info.Quantity, CustomerID = info.CustomerID });
            }
            return Lst;
        }
        #endregion
        public int Save(Order order)
        {
            int OrderID = 0;
            using (var trans = new System.Transactions.TransactionScope())
            {
                try
                {
                    OrderID = this.SaveOrder(order);
                    this.SaveOrderDevice(order.OrderDevice, OrderID);
                    trans.Complete();
                }
                catch
                {
                    trans.Dispose();
                }
            }
            return OrderID;
        }

        public void Save(List<Order> List)
        {
            int OrderID = 0;
            using (var trans = new System.Transactions.TransactionScope())
            {
                try
                {
                    foreach (var order in List)
                    {
                        OrderID = this.SaveOrder(order);
                        this.SaveOrderDevice(order.OrderDevice, OrderID);
                    }
                    trans.Complete();
                }
                catch
                {
                    trans.Dispose();
                }
            }
        }


        public PagedList<Order> GetAllOrder(DateTime? From, DateTime? To, string Distributor, int pageSize, int pageIndex)
        {
            var query = from o in m_context.Orders
                        join e in m_context.Employees on o.Createby equals e.EmployeeId into EmplJoin
                        from e2 in EmplJoin.DefaultIfEmpty()
                        join e3 in m_context.Employees on o.Createby equals e3.EmployeeId into Empl2Join
                        from e4 in Empl2Join.DefaultIfEmpty()
                        orderby o.Transdate descending
                        select new Order
                        {
                            OrderID = o.OrderID,
                            Transdate = o.Transdate,
                            Note = o.Note ?? "N/A",
                            Createby = o.Createby,
                            Modified = o.Modified,
                            CreateDate = o.CreateDate ?? DateTime.Now,
                            ModifiedDate = o.ModifiedDate ?? DateTime.Now,
                            CreatebyName = e2.Name ?? "N/A",
                            ModifiedName = e4.Name ?? "N/A"
                        };
            if (!CommonHelper.IsBlank(Distributor))
            {
                query = query.Where(o => o.Distributor.ToLower().Contains(Distributor.ToLower()));
            }
            if (!CommonHelper.IsNull(From))
            {
                query = query.Where(o => o.Transdate >= From && o.Transdate <= To);
            }
            return new PagedList<Order>(query, pageIndex, pageSize);
        }


        public PagedList<OrderDevice> GetOrderDevice(int OrderID)
        {
            var query = from o in m_context.OrderDevices
                        join d in m_context.Devices on o.DeviceID equals d.DeviceID into DeviceJoin
                        from d2 in DeviceJoin.DefaultIfEmpty()
                        where o.OrderID == OrderID
                        select new OrderDevice
                        {
                            OrderID = o.OrderID,
                            DeviceID = o.DeviceID,
                            DeviceCode = d2.DeviceCode,
                            DeviceName = d2.DeviceName,
                            OrderDeviceID = o.OrderDeviceID,
                            Quantity = o.Quantity
                        };
            return new PagedList<OrderDevice>(query, int.MaxValue, 0);
        }


        public Order GetById(int id)
        {
            return (from o in m_context.Orders where o.OrderID == id select new Order { OrderID = o.OrderID, Note = o.Note, Transdate = o.Transdate }).FirstOrDefault();
        }


        public void Delete(string orderId)
        {
            List<int> List = orderId.Split(',').Select(Int32.Parse).ToList();
            var query = from c in m_context.Orders
                        where (from id in List select id).Contains(c.OrderID)
                        select c;
            m_context.Orders.DeleteAllOnSubmit(query);
            m_context.SubmitChanges();
        }
    }
}
